using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace OliveChess
{
    class Board
    {
        // TODO: change this table as private
        public Piece[] pieces;

        public Board()
        {
            pieces = new Piece[64];
            Clear();
        }

        public void Clear()
        {
            for (int i = 0; i < 64; i++)
            {
                pieces[i] = Piece.NO_PIECE;
            }
        }

        public void Clear(int square)
        {
            pieces[square] = Piece.NO_PIECE;
        }

        /*
        * Create a new board by copy
        */
        public Board(Board p)
        {
            pieces = new Piece[64];
            for (int i = 0; i < 64; i++)
            {
                SetPiece(p.GetPiece(i), i);
            }

        }

        /**
         * Set a piece to the given square
         * 
         * @param piece
         * @param square
         */
        public void SetPiece(Piece piece, int square)
        {
            Debug.Assert((square >= 0) && (square <= 63));
            pieces[square] = piece;
        }

        /**
         * Get the content of a given square
         * 
         * @param square
         * @return
         */
        public Piece GetPiece(int square)
        {
            Debug.Assert((square >= 0) && (square <= 63)); 
            return pieces[square];
        }


        /**
         * Get all the legal moves for the given position
         * @return
         */
        /*
        public List<Move> GetLegalMoves()
        {
            List<Move> legalMoves = Engine.GetLegalMoves(this);
            //DebugDisplayMoves(possibleMoves);
            return legalMoves;
        }
         */

        /*
        private void DebugDisplayPossibleMoves(ArrayList<Move> possibleMoves) {
            System.out.println("Possible moves:");
            for(Move m : possibleMoves){
                System.out.print(m.toString() + " ");
            }
            System.out.println();
        }
        */



        /**
         * Perform a basic move or basic capture (no change of the turn)
         * 
         * @param start
         * @param dest
         */
        public void Move(int startSquare, int destSquare)
        {
            pieces[destSquare] = pieces[startSquare];
            pieces[startSquare] = Piece.NO_PIECE;
        }



        /**
         * Indicates if the square is empty
         * 
         * @param square
         * @return
         */
        public bool IsSquareEmpty(int square)
        {
            return (pieces[square] == Piece.NO_PIECE);
        }



        public bool IsEqual(Board b)
        {
            for (int i = 0; i < 64; i++) 
                if (pieces[i] != b.pieces[i]) return false;
            return true;
        }

        /*
        public override int GetHashCode()
        {
            int code = 0;
            for (int i = 0; i < 64; i++) code += ((int)this.pieces[i])*(13 ^ i);
            return code;
            
            //return this.pieces.GetHashCode();
        }
        */

        public int Evaluate(ref int[] coeff)
        {
            int result = 0;
            Piece p = Piece.NO_PIECE; ;
            for (int i = 0; i < 64; i++)
            {
                p = this.pieces[i];
                if (p != Piece.NO_PIECE)
                    result += coeff[(int)p];
            }
            return result;
        }

        public void DebugDisplay()
        {
            for (int i = 7; i >= 0; i--)
            {
                Console.WriteLine(" +---+---+---+---+---+---+---+---+");
                for (int j = 0; j < 8; j++)
                    Console.Write(" | " + ToString(pieces[i * 8 + j]));
                Console.WriteLine(" |");
            }
            Console.WriteLine(" +---+---+---+---+---+---+---+---+");
        }

        private String ToString(Piece p)
        {
            switch (p)
            {
                case Piece.W_PAWN:
                    return "P";
                case Piece.B_PAWN:
                    return "p";
                case Piece.W_KNIGHT:
                    return "N";
                case Piece.B_KNIGHT:
                    return "n";
                case Piece.W_BISHOP:
                    return "B";
                case Piece.B_BISHOP:
                    return "b";
                case Piece.W_ROOK:
                    return "R";
                case Piece.B_ROOK:
                    return "r";
                case Piece.W_QUEEN:
                    return "Q";
                case Piece.B_QUEEN:
                    return "q";
                case Piece.W_KING:
                    return "K";
                case Piece.B_KING:
                    return "k";
                default:
                    return " ";
            }
        }

    }
}